﻿using AutoMapper;
using B.S.BaseData.Domain.Entities.Logs;
using B.S.BaseData.ErrorCode;
using B.S.BaseData.ErrorCode.ErrorCodes;
using B.S.DataBase.EFCoreServiers.Dtos.Logs;
using B.S.DataBase.EFCoreServiers.IServices.Logs; // 引入日志服务接口命名空间
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Security.Claims;
using System.Threading.Tasks;

namespace B.S.BaseData.WriteAPI.Utils
{
    /// <summary>
    /// 操作日志记录特性
    /// 用于拦截控制器方法，在方法执行后自动记录操作日志。
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
    public class LogOperationAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 所属模块
        /// </summary>
        public string Module { get; }

        /// <summary>
        /// 操作类型（如：新增、修改、删除、导出等）
        /// </summary>
        public string OperationType { get; }

        /// <summary>
        /// 操作描述（详细信息）
        /// </summary>
        public string Description { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="module">所属模块（如：用户管理、角色管理等）</param>
        /// <param name="operationType">操作类型（如：新增、修改、删除、导出等）</param>
        /// <param name="description">详细描述</param>
        public LogOperationAttribute(string module, string operationType, string description = "")
        {
            Module = module;
            OperationType = operationType;
            Description = description;
        }

        /// <summary>
        /// 方法执行前的处理（本例未做特殊处理，保留扩展点）
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);
        }

        /// <summary>
        /// 方法执行后的处理，记录操作日志
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
           /* // 添加诊断日志，帮助排查问题
            var httpContext = context.HttpContext;
            var isAuthenticated = httpContext.User?.Identity?.IsAuthenticated;
            var claims = httpContext.User?.Claims?.ToList();
            
            // 临时输出诊断信息
            System.Diagnostics.Debug.WriteLine($"[LogOperation] IsAuthenticated: {isAuthenticated}");
            System.Diagnostics.Debug.WriteLine($"[LogOperation] Request Path: {httpContext.Request.Path}");
            System.Diagnostics.Debug.WriteLine($"[LogOperation] Request Method: {httpContext.Request.Method}");*/
         /*   
            if (claims != null)
            {
                foreach (var claim in claims)
                {
                    System.Diagnostics.Debug.WriteLine($"[LogOperation] Claim: {claim.Type} = {claim.Value}");
                }
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("[LogOperation] No claims found!");
            }*/

            // 先执行Action方法
            var executedContext = await next();

            // 获取当前用户信息（如无则用系统默认）
            var claims = executedContext.HttpContext?.User?.Claims;

            // 通过依赖注入获取日志服务层接口
            var logService = executedContext.HttpContext.RequestServices.GetService<IOperationLogServices>();
            if (logService == null)
            {
                return;
            }

            // 构建操作日志对象
            var log = new AddOperationLogDto
            {
                // 记录当前控制器和Action名称
                MethodName = $"{executedContext.ActionDescriptor.RouteValues["controller"]}/{executedContext.ActionDescriptor.RouteValues["action"]}",
                // 记录操作时间
                OperationTime = DateTime.Now,
                // 记录模块和操作类型
                IsModule = Module,
                IsType = OperationType,
                // 记录操作描述（优先用自定义描述，否则使用默认格式）
                Description = string.IsNullOrEmpty(Description) ? $"{Module}-{OperationType}" : Description
            };

            // 获取当前用户信息（从Claims中提取）
            int userId = Convert.ToInt32(claims?.FirstOrDefault(x => x.Type == "UserId")?.Value ?? "0");
            var userName = claims?.FirstOrDefault(x => x.Type == "UserName")?.Value ?? "系统";

            log.UserId = userId.ToString();
            log.UserName = userName;

            // 判断操作是否成功
            if (executedContext.Exception != null)
            {
                // 如果发生异常，记录失败及异常信息
                log.IsSuccess = false;
                log.ErrorMessage = executedContext.Exception.Message;
            }
            else
            {
                // 检查返回结果类型
                if (executedContext.Result is ObjectResult objectResult && objectResult.Value is ApiResult apiResult)
                {
                    // 根据ApiResult的Code判断是否成功
                    log.IsSuccess = apiResult.Code == StatusCodeEnum.Ok;

                    if (!log.IsSuccess)
                    {
                        // 记录失败原因
                        log.ErrorMessage = apiResult.Msg;
                    }
                }
                else
                {
                    // 未知类型默认认为成功
                    log.IsSuccess = true;
                }
            }

            // 调用日志服务层接口异步保存日志
            try
            {
                await logService.AddOperationLogs(log);
            }
            catch
            {
                // 日志记录失败不影响主流程
            }
        }
    }
}
